﻿namespace Hippo.Common
{
    using System;
    using System.Collections.Generic;
    using Hippo.Common;

    public abstract class CommandLineParser
    {
        // Make it easier to test the functionality by replacing the ApplicationExit method
        public static Action<int> ApplicationExit = exitCode => Environment.Exit(exitCode);

        private OptionSet options;
        private List<string> unrecognizedArguments;

        protected CommandLineParser(IConfigurationProfile configuration)
        {
            Configuration = configuration;
        }

        public IConfigurationProfile Configuration { get; private set; }

        public OptionSet Options
        {
            get
            {
                if (options == null)
                {
                    options = CreateCommandLineOptions();
                }

                return options;
            }
        }

        public IList<string> UnrecognizedArguments
        {
            get { return unrecognizedArguments; }
        }

        public void Parse(string[] args)
        {
            try
            {
                Options.Parse(args, out unrecognizedArguments);
            }
            catch (OptionsException e)
            {
                System.Console.Out.WriteLine(e.Message);
                System.Console.Out.WriteLine();
                GetHelp("{0}", ExitCode.Error);
            }
        }

        public void GetHelp(string commandLineHelpTemplate, ExitCode code)
        {
            System.Console.WriteLine(string.Format(commandLineHelpTemplate, Options));
            ApplicationExit((int)code);
        }

        public abstract OptionSet CreateCommandLineOptions();
    }
}
